home *** CD-ROM | disk | FTP | other *** search
- (c) Copyright 1991 Commodore-Amiga, Inc. All rights reserved.
- The information contained herein is subject to change without notice,
- and is provided "as is" without warranty of any kind, either expressed
- or implied. The entire risk as to the use of this information is
- assumed by the user.
-
-
-
- Opening Screens and Windows on Any Amiga
-
-
- by Ewout Walraven
-
- The release 2.0 intuition.library has a multitude of new display
- possibilities at its disposal that developers can use to improve their
- software. Many products can benefit from the flexibility that higher
- display resolutions and larger display areas offer and from the
- polished user interface available with the ``New Look'' in release
- 2.0. Because backward compatibility with 1.3 is important to many
- developers, these new features should be used in a way that will work
- with older systems.
-
- This article shows how to take advantage of the display resources
- available to Intuition under any Amiga system. This article assumes
- the reader has some knowledge of release 2.0 (V36) screens and
- windows. For more information, see the article ``An Introduction to
- V36 Screens and Windows'' from the September/October 1990 issue of
- Amiga Mail.
-
-
- Opening Full Size Screens
-
- Under pre-V36 versions of the operating system, a method commonly used
- to open a screen according to user preference was to ``clone'' the
- Workbench screen (to create a screen with the same resolution and view
- mode as the Workbench screen). Normally, applications called the
- Intuition function GetScreenData() to learn the Workbench screen's
- resolution and display mode.
-
- Programmers should no longer rely on GetScreenData() to return the
- actual resolution and display mode under release 2.0. When asked
- about the Workbench screen, the V2.0 GetScreenData() returns the video
- mode of a Hires screen, or, if the screen is interlaced, a Hires
- interlaced screen. The dimensions GetScreenData() returns will be the
- lesser of either the OSCAN_TEXT dimensions or the actual Workbench
- screen dimensions. This change to GetScreenData() prevents some
- programs developed for 1.3 from opening full size screens and windows
- under 2.0. The change had to be made to avoid confusing programs that
- couldn't handle the higher resolutions and new display modes that are
- available in release 2.0. For example, when GetScreenData() is called
- on a system using a SuperHires interlaced Workbench screen, it returns
- the dimensions and view mode of a Hires interlaced screen. If
- GetScreenData() had supplied the actual resolution instead, a program
- that assumed the resolution could not be greater than 640x400 could be
- severely crippled. The exception to this rule is a system running in
- one of the A2024 (or Hedley Hires) modes. To remain compatible with
- the V35 version of GetScreenData(), the release 2.0 version returns
- the correct dimensions of a screen in A2024 mode.
-
- Another method previously used to get information about the Workbench
- screen was to look at the GfxBase->NormalDisplayRows and
- GfxBase->NormalDisplayColumns fields. As with GetScreenData(), these
- fields contain the dimensions of a text overscan Hires (or Hires
- interlace) screen. Obviously, these fields should no longer be used
- to obtain the actual dimensions of the Workbench screen.
-
- To clone the Workbench screen under 2.0, lock the Workbench screen,
- get the screen's display mode ID, and get the necessary display
- information. The article ``An Introduction to V36 Screens and
- Windows'' from the September/October 1990 issue of Amiga Mail contains
- the example CloneWB.c which illustrates cloning the Workbench screen
- under release 2.0. Any application that wants to clone the Workbench
- screen should be prepared to handle any type of screen, because the
- user can change the Workbench screen to any type of screen they
- desire.
-
-
- PAL or NTSC?
-
- Some programs need to determine if the Workbench screen is in PAL or
- NTSC mode. Before release 2.0, it was impossible for the system to
- switch between NTSC and PAL. The PAL/NTSC state in which the machine
- booted dictated the mode of its displays. Pre-V36 systems could
- determine the PAL/NTSC state of the machine by examining a bit the in
- GfxBase->DisplayFlags field, which is set at boot time under all
- versions of the OS.
-
- Thanks to the ECS and the new system software, PAL and NTSC display
- resolutions can coexist, which obsoletes examining
- GfxBase->DisplayFlags to determine the PAL/NTSC state of a particular
- system. Release 2.0 ignores the PAL/NTSC flag after it sets the flag
- at boot time. This means that under 2.0, if the system boots as NTSC,
- it is not possible to open a PAL screen in a way that will work
- correctly with release 1.3.
-
- To respect the user setup of the Workbench rather than the default
- video mode, a program should use the V36 graphics.library and
- intuition.library functions to determine the display mode ID of the
- Workbench screen. Using that ID, an application can open a screen or
- find more information about the properties of the Workbench screen.
- The extscreen.c example at the end of this article shows how to check
- for a PAL mode screen under any version of the operating system.
-
-
- Opening Full Sized Windows
-
- Because there is no guarantee that GetScreenData() will return the
- correct screen resolution, programs can't use it to obtain the
- dimensions needed to open a full sized window. To get the correct
- screen resolution of the Workbench screen, programs have to examine
- the Height and Width fields of the Screen structure returned by
- LockPubScreen().
-
- To make supporting new and old versions of the operating system
- easier, Intuition V36 offers a way to open screens and windows that is
- compatible with previous versions of the Amiga OS. Instead of
- requiring the use of new functions to open V36 specific screens and
- windows, the OpenWindow() and OpenScreen() functions each accept an
- extended structure, ExtNewWindow and ExtNewScreen, respectively.
- These structures allow the programmer to pass tags to the V36
- OpenScreen() and OpenWindow() functions while remaining compatible
- with older versions of these functions. Older versions of Intuition
- ignore the excess baggage at the end of the structure where the tags
- are kept. These tags are partially used in V35 (a 1.3 release) to
- support the A2024 modes. Note that the ExtNewScreen and ExtNewWindow
- structures may be extended in the future, so programs must not assume
- their size is static.
-
- To use the ``New Look'', pass the SA_Pens tag and a pen array in
- ExtNewScreen. Using the New Look requires a little bit more
- responsibility from an application. Programs that aren't careful can
- experience problems with the layout of graphics and gadgets in New
- Look windows and screens. For example, a lot of programs made
- assumptions about the height of a window's title bar. Under 1.3, this
- didn't present much of a problem because the title bar height didn't
- normally change. Under 2.0, the user can choose system fonts, varying
- the size of the title bar. Graphics and gadgets rendered into the
- application's window can write over the title bar if the application
- isn't careful.
-
- The example at the end of this article, extscreen.c, illustrates how
- to open a screen and window under release 2.0, using 2.0 specific
- features if they are available, while staying compatible with older
- versions of the operating system. This example will open a screen in
- A2024 mode (under V37, V36, or V35) if the resources are available.
-
-
-
- /*
- * extscreen.c - Usage of NS_EXTENDED & NW_EXTENDED.
- *
- * Compiled with SAS C 5.10: lc -cfist -v -L extscreen.c
- */
-
- #include <intuition/intuition.h>
- #include <graphics/gfxbase.h>
- #include <graphics/displayinfo.h>
- #include <intuition/screens.h>
-
- #include <clib/exec_protos.h>
- #include <clib/intuition_protos.h>
- #include <clib/graphics_protos.h>
-
- #include <stdio.h>
- #include <stdlib.h>
-
-
- struct IntuitionBase *IntuitionBase;
- struct GfxBase *GfxBase;
- extern struct ExecBase *SysBase;
-
-
- /* To get that New Look we'll use Workbench compatible pen numbers.
- * The end of the pen array is indicated with ~0.
- * Note that the screen depth should comply with the pen numbers used.
- * I.e. specifying pen number 3 on a one bitplane screen will obviously
- * not give the desired effect.
- * A description of the pen array can be found in intuition/screens.h.
- */
-
- static UWORD dri_Pens[] =
- { 0, 1, 1, 2, 1, 3, 1, 0, 3, ~0};
-
- /* zoom/zip/zap/zop array to illustrate NW_EXTENDED */
- static UWORD zoomdata[] =
- { 30, 30, 200, 100};
-
- /* Old style requester to be compatible with < V36 */
- struct IntuiText reqtext[] = {
- { 0,1, JAM1, 10,10, NULL, NULL, NULL},
- { 0,1, JAM1, 6,3, NULL, "Continue", NULL},
- };
-
- /* local protos */
- void main(void);
- BOOL CheckPAL(STRPTR screenname);
-
- void main(void)
- {
- struct ExtNewScreen xnewscreen;
- struct ExtNewWindow xnewwindow;
- struct Screen *screen;
- struct Window *window;
- struct IntuiMessage *msg;
- struct DisplayInfo displayinfo;
- struct TagItem taglist[3];
- BOOL OpenA2024 = FALSE;
- BOOL IsV36 = FALSE;
- BOOL IsPAL;
-
- if (IntuitionBase = OpenLibrary("intuition.library", 33))
- {
- if (GfxBase = (struct GfxBase *) OpenLibrary("graphics.library", 33))
- {
-
- /* V36 check if a 10 Hz A2024 screen can be opened. If this has to be
- * done in V35 (Jumpstart), start by checking the library version
- * ofcourse. Next simply open the screen with A2024 parameters. If this
- * fails there are a couple of possibilities. The system may have run
- * out of memory or even though the user is running V35 s/he hasn't set
- * up Hedley mode. Logical step in case of failure is to try again with
- * regular parameters. Depending on the nature of the program, this could
- * be done everytime the program starts, or according to some kind of
- * user preferences setting.
- */
-
-
- /* Check for V36>. If present check Hedley (A2024) availability */
- if (GfxBase->LibNode.lib_Version >= 36)
- {
- IsV36 = TRUE;
- /* Use GetDisplayInfoData() with the DTAG_DISP to get the display info,
- * containing availability. Note that availability means that the user
- * admonitor'ed A2024, not necessarily that there is a physical A2024
- * out there.
- */
- if(GetDisplayInfoData(NULL, (UBYTE *)&displayinfo,
- sizeof(struct DisplayInfo), DTAG_DISP, A2024TENHERTZ_KEY))
- if (displayinfo.NotAvailable == 0)
- OpenA2024 = TRUE;
- }
- else
- {
- /* Check if V35. If it is indicate I want the tags added to open a
- * A2024 screen. Note that this still doesn't mean I can actually open
- * in Hedley mode.
- */
- if (GfxBase->LibNode.lib_Version == 35)
- OpenA2024 = TRUE;
- }
-
- /* Use a separate CheckPAL() function to see if how the use has set up
- * the system.
- */
- IsPAL = CheckPAL("Workbench");
-
- /* Build taglist, this is completely ignored in V33/V34 and V35 doesn't
- * recognize tags other than those A2024 ones.
- */
-
- /* Pass the A2024 tags. Note that with V36 it is easy to pass the
- * displaymodeid as a tag (SA_DisplayID) that that is not V35 compatible.
- * Also for V35 compatability this must be the first tag. */
-
- if (OpenA2024)
- {
- taglist[0].ti_Tag = NSTAG_EXT_VPMODE;
- taglist[0].ti_Data = VPF_A2024 | VPF_TENHZ;
- }
- else
- {
- /* With V36 Intuition fully supports overscan. We'll pass the
- * Overscantype used by Workbench as a tag, and specify
- * STDSCREENWIDTH/HEIGHT in the Width and Height fields of
- * the ExtNewScreen structure.
- */
- taglist[0].ti_Tag = SA_Overscan;
- taglist[0].ti_Data = OSCAN_TEXT;
- }
-
- /* Indicate we want the New Look if this system is running V36 by
- * specifying the SA_Pens tag and passing the pen array as data.
- */
- taglist[1].ti_Tag = SA_Pens;
- taglist[1].ti_Data = (ULONG) dri_Pens;
-
-
- /* End the taglist with TAG_DONE */
- taglist[2].ti_Tag = TAG_DONE;
-
-
-
- /* If V36, the overscan mode will give us the right offsets */
- xnewscreen.LeftEdge = 0;
- xnewscreen.TopEdge = 0;
-
- /* Width = 1008 if A2024, 640 if < V35, STDSCREENWIDTH if V36> */
- xnewscreen.Width = (OpenA2024) ? 1008 : (IsV36) ? STDSCREENWIDTH : 640;
-
- /* Height=1024 if A2024 & PAL, 800 if A2024 & NTSC, else STDSCREENHEIGHT */
- xnewscreen.Height = (OpenA2024) ? ((IsPAL) ? 1024 : 800) : STDSCREENHEIGHT;
-
-
- xnewscreen.Depth = 2;
- xnewscreen.DetailPen = 0;
- xnewscreen.BlockPen = 1;
-
- /* Set viewmodes to 0 if going to attempt to open in Hedley mode */
- xnewscreen.ViewModes = (OpenA2024) ? 0 : HIRES | LACE;
-
- /* Use NS_EXTENDED to tell V35 tags are on their way */
- xnewscreen.Type = CUSTOMSCREEN | NS_EXTENDED;
-
- /* Default font */
- xnewscreen.Font = NULL;
-
- xnewscreen.DefaultTitle =
- (OpenA2024) ? "VPF_A2024|VPF_TENHZ" : "HIRES|LACE";
- xnewscreen.Gadgets = NULL;
-
- /* Pass the taglist as a V35 compatible extension. V34 will ignore this */
- xnewscreen.Extension = taglist;
-
- if ((screen = OpenScreen(&xnewscreen)) == NULL)
- {
- /* Can't open screen. Might be V35 A2024 failure. Try with something
- * simpler.
- */
- xnewscreen.Width = (IsV36) ? STDSCREENWIDTH : 640;
- xnewscreen.Height = STDSCREENHEIGHT;
- xnewscreen.ViewModes = HIRES | LACE;
- xnewscreen.DefaultTitle = "HIRES|LACE";
- /* Get rid of A2024 tags, keep the others. */
- taglist[0].ti_Tag = SA_Overscan;
- taglist[0].ti_Data = OSCAN_TEXT;
- OpenA2024 = FALSE;
- screen = OpenScreen(&xnewscreen);
- /* If it still fails, give up */
- }
-
- /* If screen opened, open a simple ExtNewWindow on it and wait */
- if (screen)
- {
- /* Give me a zoom gadget on my window. */
- taglist[0].ti_Tag = WA_Zoom,
- taglist[0].ti_Data = (ULONG) zoomdata;
- taglist[1].ti_Tag = TAG_DONE;
-
- xnewwindow.LeftEdge = 0;
- xnewwindow.TopEdge = screen->BarHeight + 1;
- xnewwindow.Width = screen->Width;
- xnewwindow.Height = screen->Height - xnewwindow.TopEdge;
- xnewwindow.DetailPen = 0;
- xnewwindow.BlockPen = 1;
- xnewwindow.IDCMPFlags = CLOSEWINDOW;
- xnewwindow.Flags =
- WINDOWSIZING | WINDOWDRAG | WINDOWDEPTH | WINDOWCLOSE |
- NW_EXTENDED | SMART_REFRESH | NOCAREREFRESH | ACTIVATE;
- xnewwindow.FirstGadget = NULL;
- xnewwindow.CheckMark = NULL;
- xnewwindow.Title = "Close to exit.";
- xnewwindow.Screen = screen;
- xnewwindow.BitMap = NULL;
- xnewwindow.MinWidth = 100;
- xnewwindow.MinHeight = 50;
- xnewwindow.MaxWidth = ~0;
- xnewwindow.MaxHeight = ~0;
- xnewwindow.Type = CUSTOMSCREEN;
- /* The window extension is completely ignored if not V36 */
- xnewwindow.Extension = taglist;
-
- if (window = OpenWindow(&xnewwindow))
- {
- WaitPort(window->UserPort);
- while (msg = (struct IntuiMessage *)GetMsg(window->UserPort))
- ReplyMsg((struct Message *)msg);
- CloseWindow(window);
- }
-
-
- else
- {
- reqtext[0].IText = "Can't open window";
- AutoRequest(NULL, &reqtext[0], NULL, &reqtext[1],
- NULL, GADGETUP, 320, 60);
- }
- CloseScreen(screen);
- }
- else
- {
- reqtext[0].IText = "Can't open screen";
- AutoRequest(NULL, &reqtext[0], NULL, &reqtext[1],
- NULL, GADGETUP, 320, 60);
- }
- CloseLibrary((struct Library *) GfxBase);
- }
- CloseLibrary(IntuitionBase);
- }
- }
-
-
-
-
-
-
-
-
- /* CheckPAL returns TRUE, if the the videomode of the specified public screen (or default videmode)
- * is PAL.
- * If the screenname is NULL, the default public screen will be used.
- */
-
- BOOL CheckPAL(STRPTR screenname)
- {
- struct Screen *screen;
- ULONG modeID = LORES_KEY;
- struct DisplayInfo displayinfo;
- BOOL IsPAL;
-
- if (GfxBase->LibNode.lib_Version >= 36)
- {
- /*
- * We got V36, so lets use the new calls to find out what
- * kind of videomode the user (hopefully) prefers.
- */
-
- if (screen = LockPubScreen(screenname))
- {
- /*
- * Use graphics.library/GetVPModeID() to get the ModeID of the specified
- * screen. Will use the default public screen (Workbench most of the time)
- * if NULL It is very_ unlikely that this would be invalid, heck it's
- * impossible.
- */
- if ((modeID = GetVPModeID(&(screen->ViewPort))) != INVALID_ID)
- {
- /*
- * If the screen is in VGA mode, we can't tell whether the system is
- * PAL or NTSC. So to be fullproof we fall back to the displayinfo of
- * the default.monitor by inquiring about just the LORES_KEY
- * displaymode if we don't know. The default.monitor reflects the
- * initial video setup of the system, thus is an alias for either
- * ntsc.monitor or pal.monitor. We only use the displaymode of the
- * specified public screen if it's display mode is PAL or NTSC and NOT
- * the default.
- */
-
- if (!((modeID & MONITOR_ID_MASK) == NTSC_MONITOR_ID ||
- (modeID & MONITOR_ID_MASK) == PAL_MONITOR_ID))
- modeID = LORES_KEY;
- }
- UnlockPubScreen(NULL, screen);
- } /* if fails modeID = LORES_KEY. Can't lock screen,
- * so fall back on default monitor. */
-
- if (GetDisplayInfoData(NULL, (UBYTE *) & displayinfo,
- sizeof(struct DisplayInfo), DTAG_DISP, modeID))
- {
- if (displayinfo.PropertyFlags & DIPF_IS_PAL)
- IsPAL = TRUE;
- else
- IsPAL = FALSE; /* Currently the default monitor is always either
- * PAL or NTSC.
- */
- }
- }
- else /* < V36. The enhancements to the videosystem in
- * V36 cannot be better expressed than
- * with the simple way to determine PAL in V34.
- */
- IsPAL= (GfxBase->DisplayFlags & PAL) ? TRUE : FALSE;
-
- return(IsPAL);
- }
-
-